﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using DataAccess;
using Common;
using Common.Views;

namespace BusinessLogic
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "UsersService" in code, svc and config file together.
    /// <summary>
    /// This service contains methods which send and get data regarding 
    /// users to and from the Users, Roles and UserRoles tables in the database.
    /// </summary>
    public class UsersService : IUsersService
    {
        /// <summary>
        /// Gets a username which has the specified username
        /// </summary>
        /// <param name="username">The username of the user, which will be used to get the User</param>
        /// <returns>A user which has the specified username</returns>
        public User GetUser(string username)
        {
            return new UsersRepository().GetUser(username);
        }

        /// <summary>
        /// A method which gets all the registered users found in the database
        /// </summary>
        /// <returns>A list of all the registered users</returns>
        public IEnumerable<UsersView> GetUsernames()
        {
            return new UsersRepository().GetUsernames();
        }

        /// <summary>
        /// A method which adds a new User in the Users table in the database
        /// </summary>
        /// <param name="username">The username of the new user</param>
        /// <param name="password">The password of the new user</param>
        /// <param name="pin">The PIN number of the new user</param>
        /// <param name="name">The name of the new user</param>
        /// <param name="surname">The surname of the new user</param>
        /// <param name="email">The email of the new user</param>
        /// <param name="mobileNo">The mobile number of the new user</param>
        /// <param name="residence">The residence of the new user</param>
        /// <param name="street">The street of residence of the new user</param>
        /// <param name="town">The town of residence of the new user</param>
        /// <param name="country">The country of residence of the new user</param>
        public void AddUser(string username, string password, int pin, string name, string surname,
                       string email, string mobileNo, string residence, string street, string town, string country)
        {
            UsersRepository ur = new UsersRepository();
            RolesRepository rr = new RolesRepository();
            ur.Entity = rr.Entity;

            User u = new User();
            u.Username = username;
            u.Password = password;
            u.PIN = pin;
            u.Email = email;
            u.Name = name;
            u.Surname = surname;
            u.Residence = residence;
            u.Street = street;
            u.Town = town;
            u.Country = country;
            u.Mobile = "+356" + mobileNo;

            try
            {
                ur.Entity.Connection.Open();
                rr.Transaction = ur.Transaction = ur.Entity.Connection.BeginTransaction();

                ur.AddUser(u);
                rr.AllocateRole(u, rr.GetRole(1)); //Default role should be of Client
                ur.Transaction.Commit();
            }
            catch
            {
                ur.Transaction.Rollback();
            }
            finally
            {
                ur.Entity.Connection.Close();
            }
        }

        /// <summary>
        /// A method which is used to authenticate the user with the website according to the details in the database
        /// </summary>
        /// <param name="username">The username of the user which will be used to authenticate the user</param>
        /// <param name="token">The token which was previously generated upon registeration.
        /// This is used to authenticate the user.</param>
        /// <param name="pin">The PIN number of the user which will be used to authenticate the user</param>
        /// <returns>A boolean value which indicates whether authentication was successful or not</returns>
        public bool AuthenticateUser(string username, string token, int pin)
        {
            return new UsersRepository().AuthenticateUser(username, token, pin);
        }

        /// <summary>
        /// A method which is used to check whether a username already exists in the database
        /// </summary>
        /// <param name="username">The username for which to check if the username exists</param>
        /// <returns>A boolean value which indicates whether the username exists or not</returns>
        public bool DoesUsernameExist(string username)
        {
            return new UsersRepository().DoesUsernameExist(username);
        }

        /// <summary>
        /// A method which is used to check whether an email already exists in the database
        /// </summary>
        /// <param name="email">The email for which to check if the email exists</param>
        /// <returns>A boolean value which indicates whether the email address exists or not</returns>
        public bool DoesEmailExist(string email)
        {
            return new UsersRepository().DoesEmailExist(email);
        }

        /// <summary>
        /// A method which is used to check whether a PIN already exists in the database
        /// </summary>
        /// <param name="pin">The PIN for which to check if the PIN exists</param>
        /// <returns>A boolean value which indicates whether the PIN exists or not</returns>
        public bool DoesPinExist(int pin)
        {
            return new UsersRepository().DoesPinExist(pin);
        }
    }
}
